package com.distributed.kv.controller;

import com.distributed.kv.dto.*;
import com.distributed.kv.service.CacheService;
import com.distributed.kv.service.IdGeneratorService;
import com.distributed.kv.service.KvService;
import java.util.Map;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.ThreadMXBean;
import java.time.LocalDate;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * KV服务REST API控制器
 * 
 * 提供完整的KV操作接口:
 * 1. 单个KV操作: GET, PUT, DELETE
 * 2. 批量操作: 批量获取/创建
 * 3. 管理接口: 统计信息、缓存管理、热点数据
 */
@RestController
@RequestMapping("/kv")
@CrossOrigin(origins = "*")
public class KvController {
    
    private static final Logger logger = LoggerFactory.getLogger(KvController.class);
    
    private final KvService kvService;
    private final CacheService cacheService;
    private final IdGeneratorService idGeneratorService;
    
    public KvController(KvService kvService, 
                       CacheService cacheService,
                       IdGeneratorService idGeneratorService) {
        this.kvService = kvService;
        this.cacheService = cacheService;
        this.idGeneratorService = idGeneratorService;
    }
    
    /**
     * 获取或创建KV对
     * GET /kv/{key}
     */
    @GetMapping("/{key}")
    public ResponseEntity<KvResponse> get(@PathVariable String key) {
        try {
            KvResponse response = kvService.getOrCreate(key);
            return ResponseEntity.ok(response);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            logger.error("获取KV失败: key={}", key, e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 获取或创建KV对(带默认值)
     * POST /kv/get-or-create
     */
    @PostMapping("/get-or-create")
    public ResponseEntity<KvResponse> getOrCreate(@Valid @RequestBody KvRequest request) {
        try {
            KvResponse response = kvService.getOrCreate(request.getKey(), request.getValue());
            return ResponseEntity.ok(response);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            logger.error("获取或创建KV失败: request={}", request.getKey(), e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 更新KV对
     * PUT /kv/{key}
     */
    @PutMapping("/{key}")
    public ResponseEntity<KvResponse> update(@PathVariable String key, 
                                           @Valid @RequestBody KvRequest request) {
        try {
            KvResponse response = kvService.update(key, request.getValue());
            return ResponseEntity.ok(response);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        } catch (RuntimeException e) {
            if (e.getMessage().contains("not found")) {
                return ResponseEntity.notFound().build();
            }
            logger.error("更新KV失败: key={}", key, e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 删除KV对
     * DELETE /kv/{key}
     */
    @DeleteMapping("/{key}")
    public ResponseEntity<Void> delete(@PathVariable String key) {
        try {
            boolean deleted = kvService.delete(key);
            return deleted ? ResponseEntity.ok().build() : ResponseEntity.notFound().build();
        } catch (Exception e) {
            logger.error("删除KV失败: key={}", key, e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 批量获取或创建
     * POST /kv/batch/get-or-create
     */
    @PostMapping("/batch/get-or-create")
    public ResponseEntity<BatchResponse<KvResponse>> batchGetOrCreate(
            @Valid @RequestBody BatchRequest<String> request) {
        try {
            long startTime = System.currentTimeMillis();
            
            BatchResponse<KvResponse> response = kvService.batchGetOrCreate(request);
            response.setProcessingTimeMs(System.currentTimeMillis() - startTime);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("批量获取或创建失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 异步批量获取或创建
     * POST /kv/batch/get-or-create-async
     */
    @PostMapping("/batch/get-or-create-async")
    public CompletableFuture<ResponseEntity<BatchResponse<KvResponse>>> batchGetOrCreateAsync(
            @Valid @RequestBody BatchRequest<String> request) {
        
        return kvService.batchGetOrCreateAsync(request)
                .thenApply(ResponseEntity::ok)
                .exceptionally(e -> {
                    logger.error("异步批量获取或创建失败", e);
                    return ResponseEntity.internalServerError().build();
                });
    }
    
    /**
     * 获取热点数据
     * GET /kv/hot-keys?limit=10
     */
    @GetMapping("/hot-keys")
    public ResponseEntity<List<KvResponse>> getHotKeys(
            @RequestParam(defaultValue = "10") int limit) {
        try {
            List<KvResponse> hotKeys = kvService.getHotKeys(limit);
            return ResponseEntity.ok(hotKeys);
        } catch (Exception e) {
            logger.error("获取热点数据失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 缓存预热
     * POST /kv/cache/warm-up
     */
    @PostMapping("/cache/warm-up")
    public ResponseEntity<String> warmUpCache(@RequestBody List<String> keys) {
        try {
            kvService.warmUpCache(keys);
            return ResponseEntity.ok("缓存预热完成,处理了 " + keys.size() + " 个Key");
        } catch (Exception e) {
            logger.error("缓存预热失败", e);
            return ResponseEntity.internalServerError().body("缓存预热失败: " + e.getMessage());
        }
    }
    
    /**
     * 清理缓存
     * DELETE /kv/cache/clear
     */
    @DeleteMapping("/cache/clear")
    public ResponseEntity<String> clearCache() {
        try {
            cacheService.clear();
            return ResponseEntity.ok("缓存已清理");
        } catch (Exception e) {
            logger.error("清理缓存失败", e);
            return ResponseEntity.internalServerError().body("清理缓存失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取系统统计信息
     * GET /kv/stats
     */
    @GetMapping("/stats")
    public ResponseEntity<StatisticsResponse> getStatistics() {
        try {
            StatisticsResponse response = new StatisticsResponse();
            
            // 缓存统计
            CacheService.CacheStatistics cacheStats = cacheService.getStatistics();
            StatisticsResponse.CacheStatistics cacheStatsDto = new StatisticsResponse.CacheStatistics(
                cacheStats.getSize(),
                cacheStats.getHitCount(),
                cacheStats.getMissCount(),
                cacheStats.getHitRate(),
                cacheStats.getEvictionCount()
            );
            response.setCacheStats(cacheStatsDto);
            
            // ID生成器统计
            IdGeneratorService.IdGeneratorStats idStats = idGeneratorService.getStats();
            StatisticsResponse.IdGeneratorStats idStatsDto = new StatisticsResponse.IdGeneratorStats();
            idStatsDto.setInstanceKey(idStats.getInstanceKey());
            idStatsDto.setCurrentId(idStats.getLocalCurrentId());
            idStatsDto.setMaxId(idStats.getLocalMaxId());
            idStatsDto.setRemainingIds(idStats.getRemainingIds());
            // idStatsDto.setHasNextSegment(idStats.isHasNextSegment());
            response.setIdGeneratorStats(idStatsDto);
            
            // 系统统计
            StatisticsResponse.SystemStats systemStats = getSystemStats();
            response.setSystemStats(systemStats);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("获取统计信息失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 健康检查
     * GET /kv/health
     */
    @GetMapping("/health")
    public ResponseEntity<String> health() {
        return ResponseEntity.ok("OK");
    }
    
    /**
     * 按值分组统计访问次数
     * GET /kv/group-by/value?pattern=xxx
     */
    @GetMapping("/group-by/value")
    public ResponseEntity<List<GroupByResponse.ValueStats>> groupByValue(
            @RequestParam String pattern) {
        try {
            List<GroupByResponse.ValueStats> stats = kvService.groupByValue(pattern);
            return ResponseEntity.ok(stats);
        } catch (Exception e) {
            logger.error("按值分组查询失败: pattern={}", pattern, e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 按日期分组统计访问次数
     * GET /kv/group-by/date?startDate=2024-01-01&endDate=2024-01-31
     */
    @GetMapping("/group-by/date")
    public ResponseEntity<List<GroupByResponse.DateStats>> groupByDate(
            @RequestParam String startDate,
            @RequestParam String endDate) {
        try {
            LocalDate start = LocalDate.parse(startDate);
            LocalDate end = LocalDate.parse(endDate);
            List<GroupByResponse.DateStats> stats = kvService.groupByDate(start, end);
            return ResponseEntity.ok(stats);
        } catch (Exception e) {
            logger.error("按日期分组查询失败: startDate={}, endDate={}", startDate, endDate, e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 按日期和值分组统计访问次数
     * GET /kv/group-by/date-value?pattern=xxx&startDate=2024-01-01&endDate=2024-01-31
     */
    @GetMapping("/group-by/date-value")
    public ResponseEntity<List<GroupByResponse.DailyAccessStats>> groupByDateAndValue(
            @RequestParam String pattern,
            @RequestParam String startDate,
            @RequestParam String endDate) {
        try {
            LocalDate start = LocalDate.parse(startDate);
            LocalDate end = LocalDate.parse(endDate);
            List<GroupByResponse.DailyAccessStats> stats = kvService.groupByDateAndValue(pattern, start, end);
            return ResponseEntity.ok(stats);
        } catch (Exception e) {
            logger.error("按日期和值分组查询失败: pattern={}, startDate={}, endDate={}", pattern, startDate, endDate, e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 查找包含特定值的记录
     * GET /kv/search/value?pattern=xxx
     */
    @GetMapping("/search/value")
    public ResponseEntity<List<KvResponse>> searchByValue(
            @RequestParam String pattern) {
        try {
            List<KvResponse> results = kvService.findByValueContaining(pattern);
            return ResponseEntity.ok(results);
        } catch (Exception e) {
            logger.error("按值查询失败: pattern={}", pattern, e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    // === 私有方法 ===
    
    private StatisticsResponse.SystemStats getSystemStats() {
        StatisticsResponse.SystemStats stats = new StatisticsResponse.SystemStats();
        
        // 内存统计
        MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
        long totalMemory = memoryBean.getHeapMemoryUsage().getMax();
        long usedMemory = memoryBean.getHeapMemoryUsage().getUsed();
        long freeMemory = totalMemory - usedMemory;
        
        stats.setTotalMemoryMB(totalMemory / 1024 / 1024);
        stats.setUsedMemoryMB(usedMemory / 1024 / 1024);
        stats.setFreeMemoryMB(freeMemory / 1024 / 1024);
        
        // 线程统计
        ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
        stats.setActiveThreads(threadBean.getThreadCount());
        
        // 运行时间
        long upTime = ManagementFactory.getRuntimeMXBean().getUptime();
        stats.setUpTimeSeconds(upTime / 1000);
        
        // CPU使用率(简化版本,实际生产环境可使用更精确的方法)
        stats.setCpuUsage(0.0); // 需要第三方库或JDK14+的API
        
        return stats;
    }
}